package com.ayf.payment.game.api.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ayf.payment.game.api.cache.redis.RedisCacheUtil;
import com.ayf.payment.game.api.channel.alipay.service.AliPayService;
import com.ayf.payment.game.api.dto.*;
import com.ayf.payment.game.api.dto.alipay.AliOrderStatus;
import com.ayf.payment.game.api.dto.criteria.GameOrderCriteria;
import com.ayf.payment.game.api.dto.criteria.GameOrderPageCriteria;
import com.ayf.payment.game.api.dto.criteria.GamePlayerCashOrderBlacklistPageCriteria;
import com.ayf.payment.game.api.dto.criteria.GamePlayerCashOrderStatisticsCriteria;
import com.ayf.payment.game.api.dto.platform.SettleConfigDTO;
import com.ayf.payment.game.api.dto.response.GamePlayerCashOrderStatisticsDTO;
import com.ayf.payment.game.api.entity.GamePlayerCashOrder;
import com.ayf.payment.game.api.entity.GamePlayerGatewayConfig;
import com.ayf.payment.game.api.entity.Merchant;
import com.ayf.payment.game.api.excel.ExcelUtils;
import com.ayf.payment.game.api.exception.ParameterException;
import com.ayf.payment.game.api.gateway.GatewayUtil;
import com.ayf.payment.game.api.service.*;
import com.ayf.payment.game.api.service.platform.SettleConfigService;
import com.ayf.payment.game.api.type.CommonConstants;
import com.ayf.payment.game.api.type.PlayerCashOrderBlacklistEnum;
import com.ayf.payment.game.api.utils.*;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.swwx.charm.commons.lang.utils.BeanConvertUtils;
import com.swwx.charm.commons.lang.utils.LogPortal;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.*;

/**
 * @Author: zh-liang
 * @Date : 2020-12-09 15:02
 */

@RestController
@RequestMapping("/v/game/player")
public class GamePlayerCashController {

    @Autowired
    private MerchantPayOrderService merchantPayOrderService;
    @Autowired
    private GamePlayerCashOrderService gamePlayerCashOrderService;
    @Autowired
    private GamePlayerGatewayConfigService gamePlayerGatewayConfigService;
    @Autowired
    private AliPayService aliPayService;
    @Autowired
    private MerchantService merchantService;
    @Autowired
    private SettleConfigService settleConfigService;
    @Autowired
    private RedisCacheUtil redisCacheUtil;

    @Autowired
    private GamePlayerCashOrderBlacklistService gamePlayerCashOrderBlacklistService;

    @Autowired
    private GamePlayerCashRuleService gamePlayerCashRuleService;


    /**
     * 玩家自动提现网关配置列表查询
     */
    @GetMapping("/gatewayList")
    public CommonResult<List<GamePlayerGatewayConfig>> gatewayList(MerchantDTO merchantDTO) {
        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "商户代付订单记录查询", gamePlayerGatewayConfigService.listByMerchantId(merchantDTO.getId()));
    }

    /**
     * 添加玩家自动提现网关配置
     */
    @PostMapping("/addGateway")
    public CommonResult<?> addGateway(MerchantDTO merchantDTO, @RequestBody GamePlayerGatewayConfig config) {
        config.setMerchantId(merchantDTO.getId());
        if (StrUtil.isEmpty(config.getIp())) {
            throw new ParameterException("ip不能为空");
        }
        if (StrUtil.isEmpty(config.getPort())) {
            throw new ParameterException("端口不能为空");
        }
        if (gamePlayerGatewayConfigService.add(config)) {
            return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "添加成功");
        }
        return new CommonResult<>(CommonConstants.RETURN_ERROR, "添加失败");
    }

    /**
     * 删除玩家自动提现网关配置
     */
    @PostMapping("/delGateway")
    public CommonResult<?> delGateway(MerchantDTO merchantDTO, @RequestBody GamePlayerGatewayConfig config) {
        if (config.getId() == null) {
            throw new ParameterException("id不能为空");
        }
        config.setMerchantId(merchantDTO.getId());
        if (gamePlayerGatewayConfigService.del(config)) {
            return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "删除成功");
        }
        return new CommonResult<>(CommonConstants.RETURN_ERROR, "删除失败");
    }

    /**
     * 修改玩家自动提现网关配置
     */
    @PostMapping("/updateGateway")
    public CommonResult<?> updateGateway(MerchantDTO merchantDTO, @RequestBody GamePlayerGatewayConfig config) {
        if (config.getId() == null) {
            throw new ParameterException("id不能为空");
        }
        config.setMerchantId(merchantDTO.getId());
        if (gamePlayerGatewayConfigService.update(config)) {
            return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "修改成功");
        }
        return new CommonResult<>(CommonConstants.RETURN_ERROR, "修改失败");
    }

    /**
     * 检测玩家自动提现网关配置
     */
    @PostMapping("/checkGateway")
    public CommonResult<?> checkGateway(MerchantDTO merchantDTO, @RequestBody GamePlayerGatewayConfig config) {
        if (config.getId() == null) {
            throw new ParameterException("id不能为空");
        }
        Merchant merchant = new Merchant();
        merchant.setId(merchantDTO.getId());
        MerchantDTO dto = merchantService.selectOne(merchant);
        if (StrUtil.isEmpty(dto.getGameCashPublicKey())) {
            throw new ParameterException("请先配置秘钥");
        }
        GamePlayerGatewayConfig byId = gamePlayerGatewayConfigService.getById(config.getId());
        if (byId == null) {
            throw new ParameterException("id错误");
        }
        CommonResult<String> result = GatewayUtil.test(byId.getIp(), byId.getPort(), merchantDTO.getId(), dto.getGameCashPublicKey());
        if (result.getCode() == 200) {
            config.setStatus(1);
        } else {
            config.setStatus(2);
        }
        config.setLastCheckTime(new Date());
        gamePlayerGatewayConfigService.update(config);
        return result;
    }

    /**
     * 获取企业支付宝余额
     */
    @GetMapping("/getAliBalance")
    public CommonResult<BigDecimal> getAliBalance(MerchantDTO merchantDTO) {
        String traceId = SnowFlakeUtils.getTraceId();
        Map<String, Object> map = aliPayService.balanceQuery(traceId, merchantDTO.getId(), "---");
        BigDecimal balance = (BigDecimal) map.get("balance");
        if ("1".equals(map.get("status").toString())) {
            return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "获取成功", balance);
        }
        return new CommonResult<>(CommonConstants.RETURN_ERROR, "请检查支付宝配置是否正确。错误码：" + traceId, BigDecimal.ZERO);
    }

    /**
     * 玩家提现订单记录查询
     */
    @PostMapping("/gameOrderList")
    public CommonResult<PageDTO> gameOrderList(MerchantDTO merchantDTO, @RequestBody GameOrderPageCriteria criteria) {
        criteria.setMerchantId(merchantDTO.getId());
        PageHelper.startPage(criteria.getPageNum(), criteria.getPageSize());
        List<GamePlayerCashOrderDTO> list = gamePlayerCashOrderService.list(criteria);
        PageInfo<GamePlayerCashOrderDTO> pageInfo = new PageInfo<>(list);
        PageDTO dto = BeanConvertUtils.convert(pageInfo, PageDTO.class);
        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "商户代付订单记录查询", dto);
    }

    /**
     * 玩家提现订单记录查询汇总
     */
    @PostMapping("/gameOrderSum")
    public CommonResult<SumGamePlayerCashOrderDTO> gameOrderSum(MerchantDTO merchantDTO, @RequestBody GameOrderCriteria criteria) {
        criteria.setMerchantId(merchantDTO.getId());
        SumGamePlayerCashOrderDTO sum = gamePlayerCashOrderService.sum(criteria);
        if (sum.getSumApplyAmount() == null) {
            sum.setSumApplyAmount(BigDecimal.ZERO);
        }
        if (sum.getSumTransAmount() == null) {
            sum.setSumTransAmount(BigDecimal.ZERO);
        }
        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "商户代付订单记录查询", sum);
    }

    /**
     * 今日玩家提现订单记录查询汇总
     */
    @PostMapping("/todayGameOrderSum")
    public CommonResult<TodaySumPlayerOrderDTO> todayGameOrderSum(MerchantDTO merchantDTO) {
        GameOrderCriteria criteria = new GameOrderCriteria();
        criteria.setMerchantId(merchantDTO.getId());
        criteria.setStatus(0);
        SumGamePlayerCashOrderDTO sum = gamePlayerCashOrderService.sum(criteria);
        criteria.setStartTime(DateUtils.dateToString(new Date(), "yyyy-MM-dd 00:00:00"));
        criteria.setStatus(2);
        SumGamePlayerCashOrderDTO sum2 = gamePlayerCashOrderService.sum(criteria);
        TodaySumPlayerOrderDTO dto = new TodaySumPlayerOrderDTO();
        if (sum2.getSumApplyAmount() == null) {
            dto.setSuccessApplyAmount(BigDecimal.ZERO);
        } else {
            dto.setSuccessApplyAmount(sum2.getSumApplyAmount());
        }
        if (sum2.getSumTransAmount() == null) {
            dto.setSuccessTransAmount(BigDecimal.ZERO);
        } else {
            dto.setSuccessTransAmount(sum2.getSumTransAmount());
        }
        dto.setSuccessSum(sum2.getSum());
        dto.setAuditTransSum(sum.getSum());
        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "查询成功", dto);
    }

    /**
     * 删除玩家提现订单
     */
    @PostMapping("/delGameOrder")
    public CommonResult<PageDTO> delGameOrder(MerchantDTO merchantDTO, @RequestBody GameOrderCriteria criteria) {
        if (criteria.getIdList() == null || criteria.getIdList().size() == 0) {
            throw new ParameterException("至少选择一条订单");
        }
        criteria.setMerchantId(merchantDTO.getId());
        gamePlayerCashOrderService.delGameOrder(criteria);
        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "删除玩家提现订单成功");
    }

    /**
     * 平台支付
     */
    @PostMapping("/platformPay")
    public CommonResult<?> platformPay(MerchantDTO merchantDTO, @RequestBody GameOrderPageCriteria criteria) {
        if (criteria.getIdList() == null || criteria.getIdList().size() == 0) {
            throw new ParameterException("至少选择一条订单");
        }
        criteria.setMerchantId(merchantDTO.getId());
        List<GamePlayerCashOrderDTO> list = gamePlayerCashOrderService.list(criteria);
        LogPortal.info("查询出的数据打印：{}", JSONObject.toJSONString(list));
        String traceId = SnowFlakeUtils.getTraceId();
        for (GamePlayerCashOrderDTO dto : list) {
            if (dto.getStatus() != 0) {
                continue;
            }
            switch (dto.getPayType()) {
                case 1:
                    gamePlayerCashOrderService.addAliPayOrder(dto, traceId);
                    break;
                case 2:
                    merchantPayOrderService.createAybPayOrder(merchantDTO, dto);
                    break;
                case 3:
                    offlinePay(dto);
            }
        }
        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "平台处理成功");
    }

    /**
     * 线下支付
     */
    @PostMapping("/offlinePay")
    public CommonResult<?> offlinePay(MerchantDTO merchantDTO, @RequestBody GameOrderPageCriteria criteria) {
        if (CollUtil.isEmpty(criteria.getIdList())) {
            throw new ParameterException("至少选择一条订单");
        }
        criteria.setMerchantId(merchantDTO.getId());
        List<GamePlayerCashOrderDTO> list = gamePlayerCashOrderService.list(criteria);
        if (CollUtil.isEmpty(list)) {
            return new CommonResult<>(CommonConstants.RETURN_ERROR, "订单不存在");
        }
        for (GamePlayerCashOrderDTO dto : list) {
            offlinePay(dto);
        }
        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "线下支付成功");
    }

    /**
     * 拉取新订单
     */
    @PostMapping("/pullNewOrder")
    public CommonResult<?> pullNewOrder(MerchantDTO merchantDTO) {
        List<GamePlayerGatewayConfig> list = gamePlayerGatewayConfigService.listByMerchantId(merchantDTO.getId());
        if (CollUtil.isEmpty(list)) {
            throw new ParameterException("请先配置网关ip、端口信息");
        }
        for (GamePlayerGatewayConfig config : list) {
            if (config.getStatus() != 1) {
                continue;
            }
            //拉取最新
            GatewayUtil.pullNewOrder(config.getIp(), config.getPort(), merchantDTO.getId());
        }
        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "拉取成功");
    }

    /**
     * 手动推送订单状态
     */
    @PostMapping("/pushOrderStatus")
    public CommonResult<?> pushOrderStatus(MerchantDTO merchantDTO, @RequestBody GameOrderPageCriteria criteria) {
        if (CollUtil.isEmpty(criteria.getIdList())) {
            throw new ParameterException("至少选择一条订单");
        }
        criteria.setMerchantId(merchantDTO.getId());
        List<GamePlayerCashOrderDTO> list = gamePlayerCashOrderService.list(criteria);
        if (CollUtil.isEmpty(list)) {
            return new CommonResult<>(CommonConstants.RETURN_ERROR, "订单不存在");
        }
        for (GamePlayerCashOrderDTO dto : list) {
            gamePlayerCashOrderService.playerGatewayNotify(dto);
        }
        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "推送成功");
    }

    /**
     * 更新订单信息
     */
    @PostMapping("/updatePlayerOrder")
    public CommonResult<?> updatePlayerOrder(MerchantDTO merchantDTO, @RequestBody UpdateGamePlayerCashOrderDTO dto) {
        if (StrUtil.isEmpty(dto.getId())) {
            throw new ParameterException("订单号不能为空");
        }
        GamePlayerCashOrder byId = gamePlayerCashOrderService.findById(dto.getId());
        if (byId == null) {
            throw new ParameterException("订单不存在");
        }
        if (!Objects.equals(byId.getMerchantId(), merchantDTO.getId())) {
            throw new ParameterException("只能修改自己的订单");
        }
        dto.setId(byId.getId());
        checkData2(dto);
        GamePlayerCashRuleDTO gamePlayerCashRuleDTO = gamePlayerCashRuleService.getGamePlayerCashRuleDTOByMerchantId(merchantDTO.getId());
        BigDecimal feePrecent = new BigDecimal(gamePlayerCashRuleDTO.getFeePrecent());
        if (BigDecimal.ZERO.compareTo(feePrecent)==0) { // 手续费为0
            dto.setTransAmount(dto.getApplyAmount());
            dto.setFee(BigDecimal.ZERO);
        } else {
            BigDecimal fee = BigDecimalUtil.amtHalfDown(dto.getApplyAmount().multiply(feePrecent).multiply(BigDecimal.valueOf(0.01)));
            BigDecimal actualPayAmt = dto.getApplyAmount().subtract(fee);
            if (actualPayAmt.compareTo(BigDecimal.ZERO)<=0){
                dto.setStatus(3);
                dto.setFee(fee);
                dto.setFailReason("申请金额减去手续费必须要大于0");
            } else {
                dto.setTransAmount(actualPayAmt);
                dto.setFee(fee);
            }
        }
        gamePlayerCashOrderService.updateById(dto);
        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "修改成功");
    }

    /**
     * 导出
     */
    @PostMapping(value = "/orderExport")
    public void orderExport(MerchantDTO merchantDTO, HttpServletResponse response, @RequestBody GameOrderCriteria criteria) {
        if (CollUtil.isEmpty(criteria.getIdList())) {
            throw new ParameterException("至少选择一条订单");
        }
        criteria.setMerchantId(merchantDTO.getId());
        List<GamePlayerCashOrderDTO> list = gamePlayerCashOrderService.listexport(criteria);
        list.parallelStream().forEach(dto -> dto.setId(SnowFlakeUtils.getUniqueId()));
        String traceId = SnowFlakeUtils.getTraceId();
        String date = DateUtils.dateToString(new Date(), DateUtils.formatPattern_full_01);
        try {
            ExcelUtils.listFillExport(traceId, list, "个人支付宝批量代付" + date + ".xls", "game_order_list.xls", response);
        } catch (Exception e) {
            LogPortal.error("{} 导出失败,异常信息是:[{}]", e, traceId, e.getMessage());
        }
    }

    /**
     * 企业支付宝转账导出
     */
    @PostMapping(value = "/orderExportToCompany")
    public void orderExportToCompany(MerchantDTO merchantDTO, HttpServletResponse response, @RequestBody GameOrderCriteria criteria) {
        if (CollUtil.isEmpty(criteria.getIdList())) {
            throw new ParameterException("至少选择一条订单");
        }
        criteria.setMerchantId(merchantDTO.getId());
        List<GamePlayerCashOrderDTO> list = gamePlayerCashOrderService.listexport(criteria);
        list.parallelStream().forEach(dto -> dto.setId(SnowFlakeUtils.getUniqueId()));
        String traceId = SnowFlakeUtils.getTraceId();
        String date = DateUtils.dateToString(new Date(), DateUtils.formatPattern_full_01);
        try {
            ExcelUtils.listFillExport(traceId, list, "企业支付宝批量代付" + date + ".xls", "company_game_order_list.xls", response);
        } catch (Exception e) {
            LogPortal.error("{} 导出失败,异常信息是:[{}]", e, traceId, e.getMessage());
        }
    }

    private void offlinePay(GamePlayerCashOrderDTO dto) {
        dto.setStatus(AliOrderStatus.SUCCESS.getCode());
        dto.setFailReason("付款成功");
        dto.setPayType(3);
        if (dto.getPayType() == 1) {
            dto.setFailReason("支付宝代付-转为线下");
        } else if (dto.getPayType() == 2) {
            dto.setFailReason("爱游宝代付-转为线下");
        } else {
            dto.setFailReason("线下支付");
        }
        gamePlayerCashOrderService.updateByMerChantOrderNo(dto);
    }

    /**
     * 批量添加玩家提现订单
     */
    @PostMapping("/addGameOrder")
    public CommonResult<?> addGameOrder(HttpServletRequest request, @RequestBody String dataStr) {
        String ip = IPUtils.getIp(request);
        String traceId = SnowFlakeUtils.getTraceId();
        String merchant_id = request.getHeader("merchantId");
        if (StrUtil.isEmpty(merchant_id)) {
            LogPortal.error("{} ip:{} 添加玩家提现订单 merchant_id不能为空",traceId,ip);
            throw new ParameterException("merchant_id不能为空");
        }
        Integer merchantId = Integer.valueOf(merchant_id);
        checkIp(ip, merchantId, traceId);
        MerchantDTO merchantDTO = new MerchantDTO();
        merchantDTO.setId(merchantId);
        try {
            String singStr = request.getHeader("PayMoneyInformation");
            Merchant merchant = new Merchant();
            merchant.setId(merchantId);
            MerchantDTO dto = merchantService.selectOne(merchant);
            String asePass = RSA.decrypt(singStr, dto.getGameCashPublicKey());
            if (StrUtil.isEmpty(asePass)) {
                LogPortal.error("{} 商户ID:{} ip:{} 添加玩家提现订单 RSA解密错误",traceId,merchant_id,ip);
                throw new ParameterException("RSA解密错误，请检查秘钥，错误码:"+traceId);
            }
            dataStr = AESCoder.aes128DecryptUtf8(dataStr, asePass);
            if (StrUtil.isEmpty(dataStr)) {
                LogPortal.error("{} 商户ID:{} ip:{} 添加玩家提现订单 ip:{} AES解密错误",traceId,merchant_id,ip);
                throw new ParameterException("AES解密错误，请检查秘钥:"+traceId);
            }
            LogPortal.info("{} 商户ID:{} ip:{} 添加玩家提现订单数据内容:{}",traceId,merchant_id,ip,dataStr);
            List<GamePlayerCashOrderDTO> list = JSONArray.parseArray(dataStr, GamePlayerCashOrderDTO.class);
            LogPortal.info("{} 商户ID:{} ip:{} 添加玩家提现订单数据 申请笔数:{}",traceId,merchant_id,ip,list==null?0:list.size());
            if (CollUtil.isEmpty(list)) {
                LogPortal.error("{} 商户ID:{} ip:{} 添加玩家提现订单数据失败 申请笔数:0", traceId, merchant_id, ip);
                return new CommonResult<>(CommonConstants.RETURN_ERROR, "批量添加玩家提现订单失败，没有数据");
            }
            GamePlayerCashRuleDTO gamePlayerCashRuleDTO = gamePlayerCashRuleService.getGamePlayerCashRuleDTOByMerchantId(Integer.valueOf(merchant_id));
            BigDecimal feePrecent = new BigDecimal(gamePlayerCashRuleDTO.getFeePrecent());
            String alipayReplaceCharacter = gamePlayerCashRuleDTO.getAlipayReplaceCharacter();
            BigDecimal limitAmt = new BigDecimal(gamePlayerCashRuleDTO.getLimitAmt());
            int timeLimitStart = Integer.parseInt(gamePlayerCashRuleDTO.getTimeLimitStart());
            int timeLimitEnd = Integer.parseInt(gamePlayerCashRuleDTO.getTimeLimitEnd());
            Calendar calendar = Calendar.getInstance();
            List<GamePlayerCashOrderDTO> actualOrderList = checkData(list, ip,feePrecent,alipayReplaceCharacter);
            LogPortal.info("{} 商户ID:{} ip:{} 添加玩家提现订单数据 成功笔数:{}",traceId,merchant_id,ip, actualOrderList.size());
            actualOrderList.forEach(orderDTO -> {
                try {
                    if (orderDTO.getIsAuto()==1){
                        boolean isAlipayBlackList = gamePlayerCashOrderBlacklistService.checkBlacklist(orderDTO.getMerchantId(),orderDTO.getAccountNo(),PlayerCashOrderBlacklistEnum.ALIAPY);
                        if (isAlipayBlackList){
                            orderDTO.setIsAuto(0);
                            orderDTO.setFailReason(PlayerCashOrderBlacklistEnum.ALIAPY.getDesc());
                        }
                       BigDecimal transAmount =  orderDTO.getTransAmount();
                        if (limitAmt.compareTo(BigDecimal.ZERO)!=0 && transAmount.compareTo(limitAmt)>0){
                            orderDTO.setIsAuto(0);
                            if (StringUtils.isNotEmpty(orderDTO.getFailReason())){
                                orderDTO.setFailReason(orderDTO.getFailReason().concat("，"));
                            }
                            orderDTO.setFailReason(orderDTO.getFailReason().concat("实际付款金额超过单笔金额【"+limitAmt+"】限制"));
                        }
                        if (timeLimitStart !=0 || timeLimitEnd !=0){
                            Date applyTime = orderDTO.getApplyTime();
                            Date currentDate = DateUtils.getNowDate();
                            if (timeLimitStart == timeLimitEnd){ // 当前一个小时之内
                                calendar.setTime(currentDate);
                                calendar.set(Calendar.HOUR_OF_DAY,timeLimitStart);
                                calendar.set(Calendar.MINUTE, 0);
                                calendar.set(Calendar.SECOND, 0);
                                Date timeLimitStartDate = calendar.getTime();
                                LogPortal.debug("001 timeLimitStartDate=="+DateUtils.dateToString(timeLimitStartDate,DateUtils.formatPattern_full));
                                calendar.set(Calendar.MINUTE,59);
                                calendar.set(Calendar.SECOND, 0);
                                Date timeLimitEndDate = calendar.getTime();
                                LogPortal.debug("001 timeLimitEndDate=="+DateUtils.dateToString(timeLimitEndDate,DateUtils.formatPattern_full));
                                if (applyTime.compareTo(timeLimitStartDate)>=0 && applyTime.compareTo(timeLimitEndDate)<=0){
                                    orderDTO.setIsAuto(0);
                                    if (StringUtils.isNotEmpty(orderDTO.getFailReason())){
                                        orderDTO.setFailReason(orderDTO.getFailReason().concat("，"));
                                    }
                                    orderDTO.setFailReason(orderDTO.getFailReason().concat("时段限制【"+timeLimitStart+"】点到【"+timeLimitEnd+"】点"));
                                }
                            } else if (timeLimitEnd>timeLimitStart){ // 当天时间段
                                calendar.setTime(currentDate);
                                calendar.set(Calendar.HOUR_OF_DAY,timeLimitStart);
                                calendar.set(Calendar.MINUTE, 0);
                                calendar.set(Calendar.SECOND, 0);
                                Date timeLimitStartDate = calendar.getTime();
                                LogPortal.debug("002 timeLimitStartDate=="+DateUtils.dateToString(timeLimitStartDate,DateUtils.formatPattern_full));
                                calendar.set(Calendar.HOUR_OF_DAY,timeLimitEnd);
                                calendar.set(Calendar.MINUTE,59);
                                calendar.set(Calendar.SECOND, 0);
                                Date timeLimitEndDate = calendar.getTime();
                                LogPortal.debug("002 timeLimitEndDate=="+DateUtils.dateToString(timeLimitEndDate,DateUtils.formatPattern_full));
                                if (applyTime.compareTo(timeLimitStartDate)>=0 && applyTime.compareTo(timeLimitEndDate)<=0){
                                    orderDTO.setIsAuto(0);
                                    if (StringUtils.isNotEmpty(orderDTO.getFailReason())){
                                        orderDTO.setFailReason(orderDTO.getFailReason().concat("，"));
                                    }
                                    orderDTO.setFailReason(orderDTO.getFailReason().concat("时段限制【"+timeLimitStart+"】点到【"+timeLimitEnd+"】点"));
                                }
                            }else if (timeLimitEnd<timeLimitStart){ // 跨天时间段
                                calendar.setTime(currentDate);
                                calendar.set(Calendar.HOUR_OF_DAY,timeLimitStart);
                                calendar.set(Calendar.MINUTE, 0);
                                calendar.set(Calendar.SECOND, 0);
                                Date timeLimitStartDate = calendar.getTime();
                                LogPortal.debug("003 timeLimitStartDate=="+DateUtils.dateToString(timeLimitStartDate,DateUtils.formatPattern_full));
                                calendar.setTime(DateUtils.getDayBeforeDay(currentDate,-1));
                                calendar.set(Calendar.HOUR_OF_DAY,timeLimitEnd);
                                calendar.set(Calendar.MINUTE,59);
                                calendar.set(Calendar.SECOND, 0);
                                Date timeLimitEndDate = calendar.getTime();
                                LogPortal.debug("003 timeLimitEndDate=="+DateUtils.dateToString(timeLimitEndDate,DateUtils.formatPattern_full));
                                if (applyTime.compareTo(timeLimitStartDate)>=0 && applyTime.compareTo(timeLimitEndDate)<=0){
                                    orderDTO.setIsAuto(0);
                                    if (StringUtils.isNotEmpty(orderDTO.getFailReason())){
                                        orderDTO.setFailReason(orderDTO.getFailReason().concat("，"));
                                    }
                                    orderDTO.setFailReason(orderDTO.getFailReason().concat("时段限制【"+timeLimitStart+"】点到【"+timeLimitEnd+"】点"));
                                }
                            }
                        }
                    }
                    gamePlayerCashOrderService.addGameOrder(orderDTO);
                    if (orderDTO.getIsAuto() == 1 && orderDTO.getStatus() == 0) {
                        switch (orderDTO.getPayType()) {
                            case 1:
                                gamePlayerCashOrderService.addAliPayOrder(orderDTO, traceId);
                                break;
                            case 2:
                                merchantPayOrderService.createAybPayOrder(merchantDTO, orderDTO);
                                break;
                            case 3:
                                offlinePay(orderDTO);
                                break;
                        }
                    }
                } catch (Exception e) {
                    LogPortal.error("{} 商户ID:{} ip:{} 添加玩家提现订单失败，发生 {} 异常，异常信息为：{}，订单信息：{}", e, traceId, merchant_id, ip, e.getClass().getSimpleName(), e.getMessage(), JSON.toJSONString(orderDTO));
                }
            });
            return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "批量添加玩家提现订单成功");
        } catch (Exception e) {
            LogPortal.error("{} 商户ID:{} ip:{} 添加玩家提现订单失败，发生 {} 异常，异常信息为：{}",e,traceId,merchant_id,ip, e.getClass().getSimpleName(), e.getMessage());
            throw new ParameterException("错误码：" + traceId + "添加玩家提现订单失败，发生 " + e.getClass().getSimpleName() + " 异常，异常信息为：" + e.getMessage());
        }
    }

    private List<GamePlayerCashOrderDTO> checkData(List<GamePlayerCashOrderDTO> list, String ip,BigDecimal feePrecent,String alipayReplaceCharacter) {
        List<GamePlayerCashOrderDTO> resultList = new ArrayList<>();
        for (int i=0;i<list.size();i++) {
            GamePlayerCashOrderDTO order = list.get(i);
            order.setStatus(0);
            String error="";
            if (StrUtil.isEmpty(order.getNotifyUrl())) {
                LogPortal.error("第" + (i + 1) + "笔订单，notifyUrl为空，禁止数据输入");
                continue;
            }
            if (order.getMerchantId() == null) {
                order.setStatus(3);
                error=error.concat("商户id不能为空");
            }
            if (StrUtil.isEmpty(order.getGameOrderNo())) {
                error=error.concat("游戏订单号不能为空");
            }
            if (order.getApplyAmount() == null) {
                order.setStatus(3);
                error=error.concat("申请金额不能为空");
            }
            if (order.getPayType() == null) {
                order.setStatus(3);
                error=error.concat("付款类型不能为空");
            }
            if (order.getPayType() != 1 && order.getPayType() != 2 && order.getPayType() != 3) {
                order.setStatus(3);
                error=error.concat("付款类型错误，当前订单付款类型为：" + order.getPayType());
            }
            if (BigDecimal.ZERO.compareTo(feePrecent)==0) { // 手续费为0
                order.setTransAmount(order.getApplyAmount());
                order.setFee(BigDecimal.ZERO);
            } else {
                BigDecimal fee = BigDecimalUtil.amtHalfDown(order.getApplyAmount().multiply(feePrecent).multiply(BigDecimal.valueOf(0.01)));
                BigDecimal actualPayAmt = order.getApplyAmount().subtract(fee);
                if (actualPayAmt.compareTo(BigDecimal.ZERO)<=0){
                    order.setStatus(3);
                    order.setFee(fee);
                    error=error.concat("申请金额减去手续费必须要大于0");
                } else {
                    order.setTransAmount(actualPayAmt);
                    order.setFee(fee);
                }
            }
            if (StrUtil.isEmpty(order.getAccountNo())) {
                order.setStatus(3);
                error=error.concat("收款账号不能为空");
            }
            if (order.getAccountNo().contains(alipayReplaceCharacter)){
                order.setAccountNo(order.getAccountNo().replaceAll(alipayReplaceCharacter,"@"));
            }
            if (!Validator.isMobile(order.getAccountNo()) && !Validator.isEmail(order.getAccountNo())) {
                order.setStatus(3);
                error=error.concat("收款账号格式不正确");
            }
            if (StrUtil.isEmpty(order.getName())) {
                order.setStatus(3);
                error=error.concat("收款姓名不能为空");
            }
            if (!Validator.isChinese(order.getName())) {
                order.setStatus(3);
                error=error.concat("收款姓名格式不正确");
            }
            if (StrUtil.isEmpty(order.getGameName())) {
                order.setStatus(3);
                error=error.concat("游戏账号不能为空");
            }
            if (StrUtil.isEmpty(order.getGameAccount())) {
                order.setStatus(3);
                error=error.concat("游戏名称不能为空");
            }
            if (StrUtil.isEmpty(order.getMachineCode())) {
                order.setStatus(3);
                error=error.concat("机器码不能为空");
            }
            if (StrUtil.isEmpty(order.getApplyDate())) {
                order.setStatus(3);
                error=error.concat("申请时间不能为空");
            }
            order.setApplyTime(DateUtils.str2DateByFormat(order.getApplyDate(), "yyyy年MM月dd日HH:mm:s"));
            order.setApplyTimeIndex(DateUtils.dateToInteger(order.getApplyTime()));
            if (order.getIsAuto() == null) {
                order.setStatus(3);
                error=error.concat("是否自动代付选项不能为空");
            }
            if (order.getIsAuto() != 0 && order.getIsAuto() != 1) {
                order.setStatus(3);
                error=error.concat("是否自动代付选项错误，当前订单isAuto为：" + order.getIsAuto());
            }
            String key = "PLAYER_CASH_NO_" + order.getMerchantId() + "_" + order.getGameOrderNo();
            String value = redisCacheUtil.getObjectFromCache(key);
            if (StrUtil.isEmpty(value)) {
                redisCacheUtil.setObjectToCacheDelaySeconds(key, "abc", 60 * 60 * 24 * 2L);
            } else {
                LogPortal.error("第" + (i + 1) + "笔订单，游戏订单号已存在");
                continue;
            }
            order.setFailReason(error);
            String concat = DateUtils.dateToString(DateUtils.getNowDate(), DateUtils.formatPattern_full_03).concat(SnowFlakeUtils.getUniqueId());
            String merchantOrderNo = "GT".concat(concat);
            order.setMerchantOrderNo(merchantOrderNo);
            order.setId(SnowFlakeUtils.getUniqueId());
            order.setRequestIp(ip);
            order.setRemark("分区名称：" + order.getPartitionName() + "，游戏账号：" + order.getGameAccount());
            resultList.add(order);
        }
        return resultList;
    }


    private void checkData2(UpdateGamePlayerCashOrderDTO order) {
        if (order.getPayType() != null && order.getPayType() != 1 && order.getPayType() != 2 && order.getPayType() != 3) {
            throw new ParameterException("支付类型错误");
        }
        if (StrUtil.isNotBlank(order.getAccountNo()) && !Validator.isMobile(order.getAccountNo()) && !Validator.isEmail(order.getAccountNo())) {
            throw new ParameterException("收款账号格式不正确");
        }
        if (StrUtil.isNotBlank(order.getName()) && !Validator.isChinese(order.getName())) {
            throw new ParameterException("收款姓名格式不正确");
        }
        if (order.getApplyAmount() != null && order.getApplyAmount().compareTo(BigDecimal.ZERO) <= 0) {
            throw new ParameterException("申请金额必须大于0");
        }
        String concat = DateUtils.dateToString(DateUtils.getNowDate(), DateUtils.formatPattern_full_03).concat(SnowFlakeUtils.getUniqueId());
        String merchantOrderNo = "GT".concat(concat);
        order.setMerchantOrderNo(merchantOrderNo);
        order.setStatus(0);
        order.setFailReason("等待付款");
    }


    private void checkIp(String ip, Integer merchantId, String traceId) {
        boolean boo = true;
        List<GamePlayerGatewayConfig> list = gamePlayerGatewayConfigService.listByMerchantId(merchantId);
        for (GamePlayerGatewayConfig config : list) {
            if (ip.equals(config.getIp())) {
                boo = false;
                break;
            }
        }
        if (boo) {
            LogPortal.error("{} 商户号：{} 批量添加玩家提现失败 ip不在白名单，当前请求ip:{}", traceId, merchantId, ip);
            throw new ParameterException("错误码：" + traceId + "ip不在白名单，当前请求ip:" + ip);
        }
    }

    /**
     * 获取网站结算设置
     */
    @GetMapping("/getSettleConfig")
    public CommonResult<SettleConfigDTO> getSettleConfig() {
        SettleConfigDTO settleConfigDTO=settleConfigService.getSettleConfig();
        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "成功", settleConfigDTO);
    }

    @PostMapping("/blacklist")
    public CommonResult<PageDTO> blacklist(MerchantDTO merchantDTO, @RequestBody GamePlayerCashOrderBlacklistPageCriteria criteria) {
        criteria.setMerchantId(merchantDTO.getId());
        PageHelper.startPage(criteria.getPageNum(), criteria.getPageSize());
        List<GamePlayerCashOrderBlacklistDTO> list = gamePlayerCashOrderBlacklistService.list(criteria);
        PageInfo<GamePlayerCashOrderBlacklistDTO> pageInfo = new PageInfo<>(list);
        PageDTO dto = BeanConvertUtils.convert(pageInfo, PageDTO.class);
        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "记录查询成功",dto);
    }

    @PostMapping("/blacklist/add")
    public CommonResult<?> blacklistAdd(MerchantDTO merchantDTO, @RequestBody GamePlayerCashOrderBlacklistDTO criteria) {
        criteria.setMerchantId(merchantDTO.getId());
        if (criteria.getType() == null){
            return new CommonResult<>(CommonConstants.RETURN_ERROR, "类型不允许为空",null);
        }
        if (StringUtils.isEmpty(criteria.getName())){
            return new CommonResult<>(CommonConstants.RETURN_ERROR, "账号不允许为空",null);
        }
        try {
            gamePlayerCashOrderBlacklistService.addPlayerCashOrderBlacklist(criteria);
        } catch (Exception e) {
            if (e instanceof org.springframework.dao.DuplicateKeyException) {
                return new CommonResult<>(CommonConstants.RETURN_ERROR, "账号【".concat(criteria.getName()).concat("】已存在，请不要重复添加"),null);
            } else {
                LogPortal.error("商户ID:{} 黑名单保存发生{}异常",e,criteria.getMerchantId(),e.getClass().getName());
                return new CommonResult<>(CommonConstants.RETURN_ERROR,"保存失败，请联系技术支持",null);
            }
        }
        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "保存成功",null);
    }

    @PostMapping("/blacklist/delete")
    public CommonResult<?> blacklistDelete(@RequestBody GamePlayerCashOrderBlacklistDTO criteria) {
        gamePlayerCashOrderBlacklistService.deletePlayerCashOrderBlacklist(criteria.getId());
        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "删除成功",null);
    }

    @PostMapping("/statistics/dayStatisticsList")
    public CommonResult<GamePlayerCashOrderStatisticsDTO> dayStatisticsList(MerchantDTO merchantDTO, @RequestBody GamePlayerCashOrderStatisticsCriteria criteria) {
        criteria.setMerchantId(merchantDTO.getId());
        criteria.setStatus(2);// 付款成功
        GamePlayerCashOrderStatisticsDTO gamePlayerCashOrderStatisticsDTO = gamePlayerCashOrderService.dayStatisticsList(criteria);
        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "每日统计查询成功",gamePlayerCashOrderStatisticsDTO);
    }

    @GetMapping("/cash/rule/get")
    public CommonResult<?> cashRuleGet(MerchantDTO merchantDTO) {
        GamePlayerCashRuleDTO gamePlayerCashRuleDTO = gamePlayerCashRuleService.getGamePlayerCashRuleDTOByMerchantId(merchantDTO.getId());
        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "获取提现规则成功",gamePlayerCashRuleDTO);
    }

    @PostMapping("/cash/rule/update")
    public CommonResult<?> cashRuleUpdate(MerchantDTO merchantDTO,@RequestBody GamePlayerCashRuleDTO gamePlayerCashRuleDTO) {
        gamePlayerCashRuleDTO.setMerchantId(merchantDTO.getId());
        gamePlayerCashRuleService.saveGamePlayerCashRule(gamePlayerCashRuleDTO);
        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "保存提现规则成功",null);
    }
}
